package net.atomarrow.util;

import com.alibaba.fastjson.JSON;
import org.apache.poi.ss.formula.functions.T;

import java.io.Serializable;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.util.*;

public class ArrayUtil {
    /**
     * 列表内的数据拼接成字符串
     *
     * @param array
     * @param split
     * @return
     */
    public static String join(List<? extends Serializable> array, String split) {
        if (array == null || array.size() == 0) {
            return null;
        }
        StringBuilder sb = new StringBuilder();
		for (int i = 0; i < array.size(); i++) {
			if (i > 0) {
				sb.append(split);
			}
			sb.append(array.get(i).toString());
		}
        return sb.toString();
    }

    /**
     * 数组内的数据拼接成字符串
     *
     * @param array
     * @param split
     * @return
     */
    public static String join(Serializable[] array, String split) {
        if (array == null || array.length == 0) {
            return null;
        }
        StringBuilder sb = new StringBuilder();
		for (int i = 0; i < array.length; i++) {
			if (i > 0) {
				sb.append(split);
			}
			sb.append(array[i].toString());

		}
        return sb.toString();
    }

    /**
     * 数组内的数据用 , 拼接成字符串
     *
     * @param array
     * @return
     */
    public static String join(String[] array) {
        return join(array, ",");
    }


    /**
     * 将字符串用 , 分割成有效数组
     *
     * @param str
     * @return
     */
    public static String[] from(String str) {
        return from(str, ",", null);
    }

    /**
     * 从字符串分割有效数组
     *
     * @param str
     * @param split
     * @return
     */
    public static String[] from(String str, String split) {
        return from(str, split, null);
    }

    /**
     * 将字符串分割，并排出exceptStr
     *
     * @param str
     * @param split
     * @param exceptStr
     * @return
     */
    public static String[] from(String str, String split, String exceptStr) {
        if (StringUtil.isBlank(str)) {
            return new String[0];
        }
        String[] array = str.split(split);
        if (array.length == 0) {
            return array;
        }
        List<String> list = new ArrayList<String>();
        for (String s : array) {
            if (StringUtil.isBlank(s) || Objects.equals(s, exceptStr)) {
                continue;
            }
            list.add(s);
        }
        return list.toArray(new String[list.size()]);
    }

    /**
     * 判断数组是否包含指定内容
     *
     * @param arrays
     * @param targetValue
     * @return
     */
    public static boolean contains(String[] arrays, String targetValue) {
        if (arrays == null) {
            return false;
        }
        for (String array : arrays) {
            if (Objects.equals(array, targetValue)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 判断数组是否包含指定内容
     *
     * @param arrays
     * @param targetValue
     * @return
     */
    public static boolean contains(String[] arrays, Integer targetValue) {
        if (targetValue == null) {
            return false;
        }
        return contains(arrays, targetValue.toString());
    }

    public static <T> boolean contains(T[] array, T target) {
        if (array == null || array.length == 0) {
            return false;
        }
        for (T t : array) {
            if (Objects.equals(t, target)) {
                return true;
            }
        }

        return false;
    }

    /**
     * List中所有Item对象的指定字段提取构成数组
     *
     * @param list
     * @param columnName
     * @return
     */
    public static <E> Integer[] getIntegerArray(List<E> list, String columnName) {
        if (list.size() > 0) {
            Integer[] arrays = new Integer[list.size()];
            try {
                Class clazz = list.get(0).getClass();
                Field field = clazz.getDeclaredField(columnName);
                if (field == null) {
                    return null;
                }
                field.setAccessible(true);
                for (int i = 0; i < list.size(); i++) {
                    arrays[i] = (Integer) field.get(list.get(i));
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return arrays;
        } else {
            return new Integer[0];
        }
    }

    /**
     * 将字符串用 , 分割，然后直接转成整数数组
     *
     * @param sourceStr
     * @return
     */
    public static Integer[] getIntegerArray(String sourceStr) {
        return getIntegerArray(sourceStr, ",");
    }

    /**
     * 将字符串分割后，转成整数数组
     *
     * @param sourceStr
     * @param split
     * @return
     */
    public static Integer[] getIntegerArray(String sourceStr, String split) {
        if (StringUtil.isBlank(sourceStr)) {
            return null;
        }
        String[] strArray = sourceStr.split(split);
        Integer[] result = new Integer[strArray.length];
        for (int i = 0; i < strArray.length; i++) {
            result[i] = Integer.parseInt(strArray[i]);
        }
        return result;
    }

    /**
     * List中所有Item对象的指定字段提取构成数组
     *
     * @param list
     * @param columnName
     * @return
     */
    public static <E> String[] getStringArray(List<E> list, String columnName) {
        if (list.size() > 0) {
            String[] arrays = new String[list.size()];
            try {
                Class clazz = list.get(0).getClass();
                Field field = clazz.getDeclaredField(columnName);
                if (field == null) {
                    return null;
                }
                field.setAccessible(true);
                for (int i = 0; i < list.size(); i++) {
                    arrays[i] = (String) field.get(list.get(i));
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return arrays;
        } else {
            return new String[0];
        }
    }

    /**
     * 向数组中添加元素，返回一个新数组
     * @param array
     * @param items
     * @param <T>
     * @return
     */
    public static <T> T[] push(T[] array, T... items) {

        List<T> list = new ArrayList<>(Arrays.asList(array));
        for (T item : items) {
            list.add(item);
        }
        return list.toArray((T[]) Array.newInstance(array.getClass().getComponentType(), list.size()));
    }


    /**
     * 并集
     * @param firstArray
     * @param secondArray
     * @param <T>
     * @return
     */
    public static <T> T[] getUnionArray(T[] firstArray, T[] secondArray) {
        Set<T> set = new HashSet<T>(30);
        int firstLength = firstArray == null ? 0 : firstArray.length;
        int secondLength = secondArray == null ? 0 : secondArray.length;
        if (firstLength == 0 && secondLength == 0) {
            return (T[]) Array.newInstance(firstArray.getClass().getComponentType(), 0);
        } else if (firstLength == 0) {
            set.addAll(Arrays.asList(secondArray));
        } else if (secondLength == 0) {
            set.addAll(Arrays.asList(firstArray));
        } else {
            set.addAll(Arrays.asList(secondLength > firstLength ? secondArray : firstArray));
            for (T item : secondLength > firstLength ? firstArray : secondArray) {
                set.add(item);
            }

        }
        return set.toArray((T[]) Array.newInstance(firstArray.getClass().getComponentType(), 0));

    }

    /**
     * 获得两个数组的差集
     *
     * @param firstArray
     * @param secondArray
     * @return
     */
    public static <T> T[] getDiffArray(T[] firstArray, T[] secondArray) {
        Set<T> set = new HashSet<T>(30);
        int firstLength = firstArray == null ? 0 : firstArray.length;
        int secondLength = secondArray == null ? 0 : secondArray.length;
        if (firstLength == 0 && secondLength == 0) {
            return (T[]) Array.newInstance(firstArray.getClass().getComponentType(), 0);
        } else if (firstLength == 0) {
            set.addAll(Arrays.asList(secondArray));
        } else if (secondLength == 0) {
            set.addAll(Arrays.asList(firstArray));
        } else {
            set.addAll(Arrays.asList(secondLength > firstLength ? secondArray : firstArray));
            for (T item : secondLength > firstLength ? firstArray : secondArray) {
                if (set.contains(item)) {
                    set.remove(item);
                } else {
                    set.add(item);
                }
            }

        }
        return set.toArray((T[]) Array.newInstance(firstArray.getClass().getComponentType(), 0));
    }

    /**
     * 获得两个数组的交集
     *
     * @param firstArray
     * @param secondArray
     * @return
     */
    public static <T> T[] getIntersectionArray(T[] firstArray, T[] secondArray) {
        int firstLength = firstArray == null ? 0 : firstArray.length;
        int secondLength = secondArray == null ? 0 : secondArray.length;
        if (firstLength == 0 || secondLength == 0) {
            return (T[]) Array.newInstance(firstArray.getClass().getComponentType(), 0);
        } else {
            Set<T> set = new HashSet<T>(30);
            List<T> list = Arrays.asList(firstArray);
            for (T item : secondArray) {
                if (list.contains(item)) {
                    set.add(item);
                }
            }

            return set.toArray((T[]) Array.newInstance(firstArray.getClass().getComponentType(), 0));
        }
    }
}
